package com.qifan.alb2b.service.route;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Component;

import com.qifan.alb2b.action.front.param.PersonNum;
import com.qifan.alb2b.dao.CarInfoDao;
import com.qifan.alb2b.dao.CityInfoDao;
import com.qifan.alb2b.dao.HotelInfoDao;
import com.qifan.alb2b.dao.RouteDetailInfoDao;
import com.qifan.alb2b.domain.CarInfoDomain;
import com.qifan.alb2b.domain.GuideInfoDomain;
import com.qifan.alb2b.domain.HotelInfoDomain;
import com.qifan.alb2b.domain.RouteDetailInfoDomain;
import com.qifan.alb2b.domain.RouteInfoDomain;
import com.qifan.alb2b.exception.BusinessException;
import com.qifan.alb2b.service.cache.AppCache;
import com.qifan.alb2b.service.vo.ResourceVo;
import com.qifan.alb2b.service.vo.RouteDetailVo;
import com.qifan.alb2b.service.vo.RouteVo;
import com.qifan.alb2b.service.vo.StPriceTable;
import com.qifan.alb2b.util.Arith;
import com.qifan.alb2b.util.Constants;
import com.qifan.alb2b.util.ExchangeUtil;

/**
 * 1-6人团线路最低价格计算和标准配套价格计算
 * 【标准配套价格】=车费/人+住宿费用/人（一定记住：住宿价格=标准价格/2（包括单间、双人间、儿童占床、加床），【儿童不加床】不收费）
 * 
 * @author hc24
 * 
 */
@Component
public class SixStPrice implements IStPrice {
	public static final int MAX_PERSON_NUM=6;
	public static final String[] COLUMN=new String[]{"6","5","4","3","2","1"};
	public static final int[] PERSON_NUMS=new int[]{6,5,4,3,2,1};		
	
	private RouteDetailInfoDao routeDetailInfoDao;
	private CityInfoDao cityInfoDao;
	private HotelInfoDao hotelInfoDao;
	private CarInfoDao carInfoDao;

	public void setRouteDetailInfoDao(RouteDetailInfoDao routeDetailInfoDao) {
		this.routeDetailInfoDao = routeDetailInfoDao;
	}

	public void setCityInfoDao(CityInfoDao cityInfoDao) {
		this.cityInfoDao = cityInfoDao;
	}
	
	public void setHotelInfoDao(HotelInfoDao hotelInfoDao) {
		this.hotelInfoDao = hotelInfoDao;
	}

	public void setCarInfoDao(CarInfoDao carInfoDao) {
		this.carInfoDao = carInfoDao;
	}

	/**
	 * 根据线路route返回线路1-6人团的时候的最低价格。<br/>
	 * 如果线路上所涉及到的目的地没有设置标配价格，则最低价返回0.00代表价格未知
	 */
	public double calcLowest(RouteInfoDomain route) {
		try{
			return calc(route,PRICE_TYPE[0],MAX_PERSON_NUM);
		}catch(Exception e){
			return 0.00d;
		}
	}
	
	/**
	 * 根据线路计算1-6人团的标准配套价格
	 */
	public StPriceTable calcStTable(RouteInfoDomain route) {
		StPriceTable stPriceTable=new StPriceTable();
		List<double[]> datas=new ArrayList<double[]>();
		for(int i=0;i<PRICE_TYPE.length;i++){
			double[] prices=new double[PERSON_NUMS.length];
			for(int j=0;j<PERSON_NUMS.length;j++){
				prices[j]=calc(route, PRICE_TYPE[i], PERSON_NUMS[j]);
			}
			datas.add(prices);
		}
		stPriceTable.setColumns(COLUMN);
		stPriceTable.setDatas(datas);
		stPriceTable.setRowTypes(PRICE_TYPE);
		return stPriceTable;
	}
	
	/**
	 * 根据线路+价格类型+人数计算价格
	 * @param route 线路
	 * @param type 价格类型【"双人间","单人间","儿童占床","儿童不占床","加床"】
	 * @param personNum 人数
	 * @return
	 */
	protected double calc(RouteInfoDomain route,String type,int personNum) {
		double childScale=AppCache.configInfoMap.get("child_car_scale")==null?
				0.75:Double.parseDouble(AppCache.configInfoMap.get("child_car_scale").getConfigVal());//儿童坐车优惠比例
		List<RouteDetailInfoDomain> detailList= routeDetailInfoDao.query(route.getRouteId()).getRows();
		if(detailList.size()==0)
			throw new BusinessException("此线路暂时无法提供预定，请联系管理员");
		Set<String> routeSet=new HashSet<String>();
		for(int i=0;i<detailList.size();i++){
			if(detailList.get(i).getCityId()==null||"".equals(detailList.get(i).getCityId().trim()))
				throw new BusinessException("此线路暂时无法提供预定，请联系管理员");
			routeSet.add(detailList.get(i).getCityId());
		}
		List<Map<String, Object>> list=cityInfoDao.queryCityStdInfo(routeSet.toArray(new String[0]));
		double sumPrice=0.00d;
		for(int i=0;i<detailList.size();i++){
			RouteDetailInfoDomain detail=detailList.get(i);
			for(int j=0;j<list.size();j++){
				Map<String, Object> tempMap=list.get(j);
				if(tempMap.get("hotelPrice")==null
						||tempMap.get("carPrice")==null)
					throw new BusinessException("此线路还未提供标准价格暂时无法提供预定，请联系管理员");
				if(tempMap.get("cityId").equals(detail.getCityId())){
					double hotelPrice=0.00d;
					if((i+1)<=route.getNight())//如果有留宿则计算住宿价格
						hotelPrice=Double.parseDouble(tempMap.get("hotelPrice").toString());
					hotelPrice=ExchangeUtil.changeMoney(hotelPrice,route.getCountryId());	
					double carPrice=Double.parseDouble(tempMap.get("carPrice").toString());
					carPrice=ExchangeUtil.changeMoney(carPrice,route.getCountryId());
					if(type.equals("单人间")){
						double tempPrice=Arith.add(hotelPrice, Arith.div(carPrice, personNum, Constants.XIAOSHU));
						sumPrice=Arith.add(sumPrice, tempPrice);
					}else if(type.equals("双人间")||type.equals("加床")){
						double tempPrice=Arith.add(Arith.div(hotelPrice, 2, Constants.XIAOSHU), Arith.div(carPrice, personNum, Constants.XIAOSHU));
						sumPrice=Arith.add(sumPrice, tempPrice);
					}else if(type.equals("儿童占床")){
						double childCarPrice=Arith.mul(Arith.div(carPrice, 2, Constants.XIAOSHU), childScale);//儿童的车价格
						childCarPrice=Arith.roundCeiling(childCarPrice, Constants.XIAOSHU);
						double tempPrice=Arith.add(Arith.div(hotelPrice, personNum, Constants.XIAOSHU), childCarPrice);
						sumPrice=Arith.add(sumPrice, tempPrice);
					}else if(type.equals("儿童不占床")){
						double childCarPrice=Arith.mul(Arith.div(carPrice, personNum, Constants.XIAOSHU), childScale);//儿童的车价格
						childCarPrice=Arith.roundCeiling(childCarPrice, Constants.XIAOSHU);
						sumPrice=Arith.add(sumPrice, childCarPrice);
					}else{
						throw new RuntimeException("SixStPrice-calc-type error!");
					}
					break;
				}
			}
		}
		return Arith.roundCeiling(sumPrice,0);//只入不舍到整数
	}

	/**
	 * 初始化1-6人团的标配资源
	 */
	public void initStRes(RouteVo routeVo) {
		List<RouteDetailVo> detailList= routeVo.getDetailVoList();
		Set<String> cityIdSet=new HashSet<String>();
		Set<String> hotelIdSet=new HashSet<String>();
		Set<String> carIdSet=new HashSet<String>();
		for(int i=0;i<detailList.size();i++){
			cityIdSet.add(detailList.get(i).getRouteDetail().getCityId());
		}
		String[] cityIds=cityIdSet.toArray(new String[]{});
		List<Map<String, Object>> list=cityInfoDao.queryCityStdInfo(cityIds);
		for(int i=0;i<list.size();i++){
			hotelIdSet.add(list.get(i).get("hotelId").toString());
			carIdSet.add(list.get(i).get("carId").toString());
		}
		
		String countryId=routeVo.getRoute().getCountryId();//国家ID
		List<HotelInfoDomain> hotelList=hotelInfoDao.queryHotelsByIds(hotelIdSet.toArray(new String[]{}));
		List<CarInfoDomain> carList=carInfoDao.queryCarsByIds(carIdSet.toArray(new String[]{}));
		for(int i=0;i<detailList.size();i++){
			RouteDetailVo detailVo=detailList.get(i);
			RouteDetailInfoDomain routeDetail=detailVo.getRouteDetail();
			String cityId=routeDetail.getCityId();
			List<ResourceVo> resList=new ArrayList<ResourceVo>();
			
			if((i+1)<=routeVo.getRoute().getNight()){//如果有留宿则设置
				//查找标配酒店
				for(HotelInfoDomain hotel:hotelList){
					if(hotel.getCityId().equals(cityId)){
						ResourceVo resVo=new ResourceVo();
						hotel.setStPrice(ExchangeUtil.changeMoney(hotel.getStPrice(),countryId));//存储汇率转化后的价格
						resVo.setResource(hotel);
						resVo.setResType(Constants.RES_TYPE_HOTEL);
						resVo.setResId(hotel.getHotelId());
						resVo.setIsStd(0);//设置标配资源
						resList.add(resVo);
						break;
					}
				}
			}
			
			//查找标配接送
			for(CarInfoDomain car:carList){
				if(car.getCityId().equals(cityId)){
					ResourceVo resVo=new ResourceVo();
					car.setPrice((float) ExchangeUtil.changeMoney(car.getPrice(), countryId));//存储汇率转化后的价格
					resVo.setResource(car);
					resVo.setResType(Constants.RES_TYPE_CAR);
					resVo.setResId(car.getCarId());		
					resVo.setIsStd(0);//设置标配资源
					resList.add(resVo);
					break;
				}
			}
			
			detailVo.setResList(resList);			
		}// end for
	}

	public double[] calcTotalPrice(PersonNum personNum, StPriceTable spt) {
		if(personNum.getTotal()>6)
			throw new BusinessException("超出1-6人团的最大人数限制");
		double[] prices=new double[spt.getRowTypes().length];
		List<double[]> datas=spt.getDatas();
		int index=6-personNum.getTotal();
		prices[0]=personNum.getDoubleRoom()==0?0:datas.get(0)[index]*personNum.getDoubleRoom();
		prices[1]=personNum.getSingleRoom()==0?0:datas.get(1)[index]*personNum.getSingleRoom();
		prices[2]=personNum.getChildHaveBed()==0?0:datas.get(2)[index]*personNum.getChildHaveBed();
		prices[3]=personNum.getChildNoBed()==0?0:datas.get(3)[index]*personNum.getChildNoBed();
		prices[4]=personNum.getAddBed()==0?0:datas.get(4)[index]*personNum.getAddBed();
		personNum.setIndex(index);
		return prices;
	}

}
